package cn.ccenjie.wsy.config.jwt;

import cn.ccenjie.wsy.properties.WsyAuthProperties;
import cn.ccenjie.wsy.utils.HttpUtils;
import cn.ccenjie.wsy.vo.Resp;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@Slf4j
public class JwtAuthenticationFilter extends BasicAuthenticationFilter {

    @Autowired
    private WsyAuthProperties wsyAuthProperties;


    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    @SuppressWarnings("unchecked")
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {

        List<String> expath = wsyAuthProperties.getExpath();
        AntPathMatcher antPathMatcher = new AntPathMatcher();
        for(String epath : expath) {
            if(antPathMatcher.match(epath, request.getRequestURI())) {
                chain.doFilter(request, response);
                return;
            }
        }

        if(new AntPathMatcher().match("/login.html", request.getRequestURI())) {
            chain.doFilter(request, response);
            return;
        }

        String hader = HttpUtils.getHader(Jwtconst.HEADER, request);
        if(StringUtils.isEmpty(hader)) {
            Object obj = HttpUtils.getParam(Jwtconst.HEADER, request);
            if(obj != null) {
                hader = obj.toString();
            }
        }
        if(StringUtils.isEmpty(hader)) {
            HttpUtils.wrire(response, Resp.noAuth("未授权访问"));
            return;
        }

        String jwt = hader.replace(Jwtconst.TOKEN_PREFIX, "");

        try {

            Claims body = Jwts.parser().setSigningKey(Jwtconst.SIG_KEY).parseClaimsJws(jwt).getBody();
            List<SimpleGrantedAuthority> grantedAuthorities = (List<SimpleGrantedAuthority>) body.get(Jwtconst.AUTHORITYS_KEY);
            User principal = new User(body.getSubject(), "", grantedAuthorities);
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(principal, null, grantedAuthorities);
            SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);

        }catch (ExpiredJwtException e) {
            HttpUtils.wrire(response, Resp.noAuth("登录已过期"));
            return;
        }catch (Exception e) {
            HttpUtils.wrire(response, Resp.noAuth("令牌无效"));
            return;
        }

        super.doFilterInternal(request, response, chain);
    }
}


